#include "frmsetting.h"
#include "ui_frmsetting.h"
#include "mainwindow.h"
#include "stdio.h"
using namespace std;
FrmSetting::FrmSetting(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::FrmSetting)
{
    this->m_parent=(MainWindow*)parent;
    ui->setupUi(this);
    init();
}

FrmSetting::~FrmSetting()
{
    delete ui;
}
void FrmSetting::sitch_tab(int idx)
{
    ui->myTabs->setCurrentIndex(idx);
}
//初始化
void FrmSetting::init()
{
    //初始化COMB
    int count = m_parent->UHF_TAG_MAX_WORD_NUMBER*16;
    //selection
    for (int i=0;i<count;i++) {
        ui->cbbSelPointer->addItem(QString("%1").arg(i),i);
        ui->cbbSelMaskBitsLen->addItem(QString("%1").arg(i+1),i+1);
    }

    count=m_parent->UHF_TAG_MAX_WORD_NUMBER;//1 Word = 2 Bytes
    for (int i=0;i<count;i++) {
        ui->cbbReadWordPtr->addItem(QString("%1").arg(i),i);
        ui->cbbReadWordCnt->addItem(QString("%1").arg(i+1),i+1);
        ui->cbbWriteWordPtr->addItem(QString("%1").arg(i),i);
        ui->cbbWriteWordCnt->addItem(QString("%1").arg(i+1),i+1);
    }

    //设置可输入
    ui->cbbSelPointer->setEditable(true);
    ui->cbbSelMaskBitsLen->setEditable(true);
    ui->cbbReadWordPtr->setEditable(true);
    ui->cbbReadWordCnt->setEditable(true);
    ui->cbbWriteWordPtr->setEditable(true);
    ui->cbbWriteWordCnt->setEditable(true);

    //绑定参数
    bind_data();
    sitch_tab(1);
    ui->tab_cmds->setCurrentIndex(0);
}
void FrmSetting::bind_data()
{
    SELECTION* m_sel=m_parent->invenParams->m_sel;
    META_FLAGS* m_metaFlags=m_parent->invenParams->m_metaFlags;
    INVEN_READ* m_read=m_parent->invenParams->m_read;
    EMBEDDED_WRITE* m_write=m_parent->invenParams->m_write;
    EMBEDDED_Lock* m_lock=m_parent->invenParams->m_lock;

    /* select option */
    ui->ckbSelEnable->setChecked(m_sel->m_enable);
    ui->fra_selection->setEnabled(m_sel->m_enable);

    ui->cbbSelTarget->setCurrentIndex(m_sel->m_target);
    ui->cbbSelAction->setCurrentIndex(m_sel->m_action);
    ui->cbbSelMemBank->setCurrentIndex(m_sel->m_memBank);
    //设置值
    ui->cbbSelPointer->setCurrentText(QString(m_sel->m_pointer));
    ui->cbbSelMaskBitsLen->setCurrentText(QString(m_sel->m_maskbits_len));

    int bit_len=m_sel->m_maskbits_len;
    if(bit_len>0)
    {
        int need_bytes_len=bit_len/8 + (bit_len%8==0?0:1);
        char strs_maskBits[need_bytes_len*2+1];
        memset(strs_maskBits,'\0',sizeof(strs_maskBits));
        BytesToHexStr(m_sel->m_maskbits,need_bytes_len,strs_maskBits);
        ui->txbSelMaskBits->setText(QString(strs_maskBits).toUpper());
    }
    /* meta option*/
    ui->ckbMetaEnable->setChecked(m_metaFlags->m_enable);
    ui->fra_meta->setEnabled(m_metaFlags->m_enable);

    ui->ckbMetaEPC->setChecked(m_metaFlags->m_EPC);
    ui->ckbMetaAntennaID->setChecked(m_metaFlags->m_antennaID);
    ui->ckbMetaTimestamp->setChecked(m_metaFlags->m_timestamp);
    ui->ckbMetaFrequency->setChecked(m_metaFlags->m_frequency);
    ui->ckbMetaRSS->setChecked(m_metaFlags->m_RSSI);
    ui->ckbMetaReadCnt->setChecked(m_metaFlags->m_readCnt);
    ui->ckbMetaTagData->setChecked(m_metaFlags->m_tagData);

    /*inventory read */
    ui->ckbReadEnable->setChecked(m_metaFlags->m_tagData);
    ui->fra_read_tag_data->setEnabled(m_metaFlags->m_tagData);

    ui->cbbReadMemBank->setCurrentIndex(m_read->m_memBank);
    //设置值
    ui->cbbReadWordPtr->setCurrentText(QString(m_read->m_wordPtr));
    ui->cbbReadWordCnt->setCurrentText(QString(m_read->m_wordCnt));

    /*embedded commands---- write*/
    ui->ckbWriteEnable->setChecked(m_write->m_enable);
    ui->fra_embd_cmd_write->setEnabled(m_write->m_enable);

    ui->cbbWriteMemBank->setCurrentIndex(m_write->m_memBank);
    //设置值
    ui->cbbWriteWordPtr->setCurrentText(QString(m_write->m_wordPtr));
    ui->cbbWriteWordCnt->setCurrentText(QString(m_write->m_wordCnt));

    int bytes_data_len = m_write->m_wordCnt*2;
    if(bytes_data_len>0)
    {
        char strs_data[bytes_data_len*2+1];
        memset(strs_data,'\0',sizeof(strs_data));
        BytesToHexStr(m_write->m_datas,bytes_data_len,strs_data);
        ui->txbWriteDatas->setText(QString(strs_data).toUpper());
    }


    /* embedded lock */
    ui->ckbLockEnable->setChecked(m_lock->m_enable);
    ui->fra_embd_cmd_lock->setEnabled(m_lock->m_enable);

    ui->ckbLockUserMem->setChecked(m_lock->m_userMemSelected );
    ui->ckbLockTIDMem->setChecked(m_lock->m_TIDMemSelected);
    ui->ckbLockEPCMem->setChecked(m_lock->m_EPCMemSelected);
    ui->ckbLockAccessPwd->setChecked(m_lock->m_accessPwdSelected);
    ui->ckbLockKillPwd->setChecked(m_lock->m_killPwdSelected);

    ui->cbbLockUserMem->setCurrentIndex(m_lock->m_userMem);
    ui->cbbLockTIDMem->setCurrentIndex(m_lock->m_TIDMem);
    ui->cbbLockEPCMem->setCurrentIndex(m_lock->m_EPCMem);
    ui->cbbLockAccessPwd->setCurrentIndex(m_lock->m_accessPwd);
    ui->cbbLockKillPwd->setCurrentIndex(m_lock->m_killPwd);

    ui->cbbLockUserMem->setEnabled(m_lock->m_userMemSelected);
    ui->cbbLockTIDMem->setEnabled(m_lock->m_TIDMemSelected);
    ui->cbbLockEPCMem->setEnabled(m_lock->m_EPCMemSelected);
    ui->cbbLockAccessPwd->setEnabled(m_lock->m_accessPwdSelected);
    ui->cbbLockKillPwd->setEnabled(m_lock->m_killPwdSelected);

    //other
    //access
    UINT32 m_accessPwd = m_parent->invenParams->m_accessPwd;

    char strs_acc[9]={'\0'};
    Numeric2HexStr(m_accessPwd,strs_acc,4,false);
    ui->txbAccessPwd->setText(QString(strs_acc).toUpper());

    UINT32 m_killPwd = m_parent->invenParams->m_killPwd;
    char strs_kil[9]={'\0'};
    Numeric2HexStr(m_killPwd,strs_kil,4,false);
    ui->txbKillPwd->setText(QString(strs_kil).toUpper());

    //timeout
    UINT32 m_timeout=m_parent->invenParams->m_timeout;

    ui->txbTimeout->setText(QString("%1").arg(m_timeout));

}

int FrmSetting::save_data()
{
    SELECTION* m_sel=m_parent->invenParams->m_sel;
    META_FLAGS* m_metaFlags=m_parent->invenParams->m_metaFlags;
    INVEN_READ* m_read=m_parent->invenParams->m_read;
    EMBEDDED_WRITE* m_write=m_parent->invenParams->m_write;
    EMBEDDED_Lock* m_lock=m_parent->invenParams->m_lock;

    /* select option */
    m_sel->m_enable = ui->ckbSelEnable->isChecked();

    if(m_sel->m_enable)
    {
        m_sel->m_target =(BYTE)(ui->cbbSelTarget->currentIndex());
        m_sel->m_action =(BYTE) ui->cbbSelAction->currentIndex();
        m_sel->m_memBank = (BYTE)ui->cbbSelMemBank->currentIndex();

        m_sel->m_pointer = ui->cbbSelPointer->currentData().toInt();

        int m_maskbits_len = ui->cbbSelMaskBitsLen->currentData().toInt();

        if(m_maskbits_len>m_parent->UHF_TAG_MAX_WORD_NUMBER*16)
        {
            m_sel->m_enable=false;
            ui->lbl_info->setText(QString("Slection: Mask Bits Length is too big, must < %1!").arg(m_parent->UHF_TAG_MAX_WORD_NUMBER*16));
            sitch_tab(0);
            ui->cbbSelMaskBitsLen->setFocus();
            return -1;
        }
        else if(m_maskbits_len <= 0 ){
            m_sel->m_enable=false;
            ui->lbl_info->setText(QString("Slection: Mask Bits Length must > 0!"));
            sitch_tab(0);
            ui->cbbSelMaskBitsLen->setFocus();
            return -1;
        }

        QString qstrs = ui->txbSelMaskBits->text().trimmed();
        if((qstrs.size()%2) != 0)
        {
            m_sel->m_enable=false;
            ui->lbl_info->setText(QString("Slection: Mask Bits Data's length not multiples of 2 "));
            sitch_tab(0);
            ui->txbSelMaskBits->setFocus();
            return -1;
        }
        int bit_len= m_maskbits_len;
        int bytes_len = qstrs.size()/2;
        int need_bytes_len=bit_len/8 + (bit_len%8==0?0:1);
        if(need_bytes_len > bytes_len)
        {
            m_sel->m_enable=false;
            ui->lbl_info->setText(QString("Slection: Mask Bits Length(%1 bytes) > Mask Bits Data's length(%2 bytes)").arg(need_bytes_len).arg(bytes_len));
            sitch_tab(0);
            ui->txbSelMaskBits->setFocus();
            return -1;
        }
        BYTE byts[need_bytes_len];//={0};
        memset(byts,'\0',sizeof(byts));
        bool b=HexStrToBytes(qstrs.toStdString().data(),byts,need_bytes_len);
        if(!b)
        {
            m_sel->m_enable=false;
            ui->lbl_info->setText(QString("Slection: Mask Bits Data's format(Hex) error!"));
            sitch_tab(0);
            ui->txbSelMaskBits->setFocus();
            return -1;
        }
        memcpy(m_sel->m_maskbits,byts,need_bytes_len);
        m_sel->m_maskbits_len = m_maskbits_len;
    }


    /* meta option*/
    m_metaFlags->m_enable = ui->ckbMetaEnable->isChecked();
    if(m_metaFlags->m_enable)
    {
        m_metaFlags->m_EPC = ui->ckbMetaEPC->isChecked();
        m_metaFlags->m_frequency =  ui->ckbMetaFrequency->isChecked();
        m_metaFlags->m_readCnt = ui->ckbMetaReadCnt->isChecked();
        m_metaFlags->m_RSSI = ui->ckbMetaRSS->isChecked();
        m_metaFlags->m_tagData = ui->ckbMetaTagData->isChecked();
        m_metaFlags->m_timestamp = ui->ckbMetaTimestamp->isChecked();
        m_metaFlags->m_antennaID = ui->ckbMetaAntennaID->isChecked();
        if(m_metaFlags->m_EPC || m_metaFlags->m_frequency
                || m_metaFlags->m_readCnt || m_metaFlags->m_RSSI
                || m_metaFlags->m_tagData || m_metaFlags->m_timestamp
                || m_metaFlags->m_antennaID)
        {
        }
        else {
            m_metaFlags->m_EPC=true;
            m_metaFlags->m_antennaID=true;
            m_metaFlags->m_enable = true;
            ui->lbl_info->setText(QString("Meta flags: No options have be selected !"));
            sitch_tab(1);
            return -1;
        }
    }

    /*inventory read */
    m_metaFlags->m_tagData= ui->ckbReadEnable->isChecked();
    if(m_metaFlags->m_tagData)
    {
        m_read->m_memBank =(BYTE)ui->cbbReadMemBank->currentIndex();

        m_read->m_wordPtr = ui->cbbReadWordPtr->currentData().toInt();
        int count_val = ui->cbbReadWordCnt->currentData().toInt();

        if(count_val > m_parent->UHF_TAG_MAX_WORD_NUMBER)
        {
            m_metaFlags->m_tagData=false;
            ui->lbl_info->setText(QString("Inventory read: Word Count is too big, must < %1!").arg(m_parent->UHF_TAG_MAX_WORD_NUMBER));
            sitch_tab(2);
            ui->cbbReadWordCnt->setFocus();
            return -1;
        }
        else if(count_val<= 0)
        {
            m_metaFlags->m_tagData=false;
            ui->lbl_info->setText(QString("Inventory read: Word Count must > 0 !"));
            sitch_tab(2);
            ui->cbbReadWordCnt->setFocus();
            return -1;
        }
        m_read->m_wordCnt = count_val;
    }

    /*embedded commands---- write*/
    m_write->m_enable = ui->ckbWriteEnable->isChecked();
    if(m_write->m_enable)
    {
        m_write->m_memBank =(BYTE)ui->cbbWriteMemBank->currentIndex();
        m_write->m_wordPtr = ui->cbbWriteWordPtr->currentData().toInt();
        if(m_write->m_memBank==1 && m_write->m_wordPtr < 2)
        {
            m_write->m_enable=false;
            m_write->m_wordPtr=2;//reset
            ui->lbl_info->setText(QString("Write Commands: Word Start of EPC memory must >= 2!"));
            sitch_tab(3);
            ui->tab_cmds->setCurrentIndex(0);
            ui->cbbWriteWordPtr->setFocus();
            return -1;

        }
        int count_val = ui->cbbWriteWordCnt->currentData().toInt();

        if(count_val > m_parent->UHF_TAG_MAX_WORD_NUMBER)
        {
            m_write->m_enable=false;
            ui->lbl_info->setText(QString("Write Commands: Word Count is too big, must < %1!").arg(m_parent->UHF_TAG_MAX_WORD_NUMBER));
            sitch_tab(3);
            ui->tab_cmds->setCurrentIndex(0);
            ui->cbbWriteWordCnt->setFocus();
            return -1;
        }
        else if (count_val <= 0 ){
            m_write->m_enable=false;
            ui->lbl_info->setText(QString("Write Commands: Word Count must > 0!"));
            sitch_tab(3);
            ui->tab_cmds->setCurrentIndex(0);
            ui->cbbWriteWordCnt->setFocus();
            return -1;
        }

        QString qstrs = ui->txbWriteDatas->text().trimmed();
        if((qstrs.size()%2) != 0)
        {
            m_write->m_enable=false;
            ui->lbl_info->setText(QString("Write Commands: New Data's char length not multiples of 2"));
            sitch_tab(3);
            ui->tab_cmds->setCurrentIndex(0);
            ui->txbWriteDatas->setFocus();
            return -1;
        }
        int bytes_len = qstrs.size()/2;
        int need_bytes_len = count_val * 2;
        if(need_bytes_len > bytes_len)
        {
            m_write->m_enable=false;
            ui->lbl_info->setText(QString("Write Commands: Word Count(%1 bytes) > New Data's length(%2 bytes)").arg(need_bytes_len).arg(bytes_len));
            sitch_tab(3);
            ui->tab_cmds->setCurrentIndex(0);
            ui->txbWriteDatas->setFocus();
            return -1;
        }
        BYTE byts[need_bytes_len];//={0};
        memset(byts,'\0',sizeof(byts));
        bool b=HexStrToBytes(qstrs.toStdString().data(),byts,need_bytes_len);
        if(!b)
        {
            m_write->m_enable=false;
            ui->lbl_info->setText(QString("Write Commands: New Data's format(Hex) error!"));
            sitch_tab(3);
            ui->tab_cmds->setCurrentIndex(0);
            ui->txbWriteDatas->setFocus();
            return -1;
        }
        memcpy(m_write->m_datas,byts,need_bytes_len);
        m_write->m_wordCnt = count_val;
    }
    /* embedded command-----lock */
    m_lock->m_enable = ui->ckbLockEnable->isChecked();
    if(m_lock->m_enable)
    {
        m_lock->m_userMemSelected = ui->ckbLockUserMem->isChecked();
        m_lock->m_TIDMemSelected = ui->ckbLockTIDMem->isChecked();
        m_lock->m_EPCMemSelected = ui->ckbLockEPCMem->isChecked();
        m_lock->m_accessPwdSelected = ui->ckbLockAccessPwd->isChecked();
        m_lock->m_killPwdSelected = ui->ckbLockKillPwd->isChecked();

        m_lock->m_userMem  = ui->cbbLockUserMem->currentIndex();
        m_lock->m_TIDMem = ui->cbbLockTIDMem->currentIndex();
        m_lock->m_EPCMem = ui->cbbLockEPCMem->currentIndex();
        m_lock->m_accessPwd = ui->cbbLockAccessPwd->currentIndex();
        m_lock->m_killPwd = ui->cbbLockKillPwd->currentIndex();
        if(m_lock->m_userMemSelected || m_lock->m_TIDMemSelected
                || m_lock->m_EPCMemSelected || m_lock->m_accessPwdSelected
                || m_lock->m_killPwdSelected)
        {
        }
        else {
            m_lock->m_enable=false;
            ui->lbl_info->setText(QString("Lock Commands: No options have be selected!"));
            sitch_tab(3);
            ui->tab_cmds->setCurrentIndex(1);
            return -1;
        }
    }

    //other
    //access pwd
    QString qstrs=ui->txbAccessPwd->text().trimmed();

    if(qstrs.size() != 8)
    {
        ui->lbl_info->setText(QString("Other: Access Password length must be 4 bytes in hex format!"));
        sitch_tab(4);
        ui->txbAccessPwd->setFocus();
        return -1;
    }
    bool ok=false;
    uint accessPwd=qstrs.toUInt(&ok,16);
    if(!ok)
    {
        ui->lbl_info->setText(QString("Other: Access Password length must be 4 bytes in hex format!"));
        sitch_tab(4);
        ui->txbAccessPwd->setFocus();
        return -1;
    }
    m_parent->invenParams->m_accessPwd = accessPwd;

    //kill pwd
    qstrs=ui->txbKillPwd->text().trimmed();

    if(qstrs.size() != 8)
    {
        ui->lbl_info->setText(QString("Other: Kill Password length must be 4 bytes in hex format!"));
        sitch_tab(4);
        ui->txbKillPwd->setFocus();
        return -1;
    }
    ok=false;
    uint killPwd=qstrs.toUInt(&ok,16);
    if(!ok)
    {
        ui->lbl_info->setText(QString("Other: Kill Password length must be 4 bytes in hex format!"));
        sitch_tab(4);
        ui->txbKillPwd->setFocus();
        return -1;
    }
    m_parent->invenParams->m_killPwd = killPwd;

    /* timeout */
    qstrs=ui->txbTimeout->text().trimmed();
    ok=false;
    UINT timeout=qstrs.toUInt(&ok,10);
    if(!ok)
    {
        ui->lbl_info->setText(QString("Other: Timeout value error!"));
        sitch_tab(4);
        ui->txbTimeout->setFocus();
        return -1;
    }
    if(timeout < 5000)
    {
        ui->lbl_info->setText(QString("Other: Timeout value must > 5000 ms!"));
        sitch_tab(4);
        ui->txbTimeout->setFocus();
        return -1;
    }
    m_parent->invenParams->m_timeout = timeout;

    return NO_ERR;
}

void FrmSetting::on_btn_OK_clicked()
{
    int iret= save_data();
    if(iret== NO_ERR)
        this->close();
}

void FrmSetting::on_btn_Cancel_clicked()
{
    this->close();
}


void FrmSetting::on_ckbSelEnable_stateChanged(int arg1)
{
    ui->fra_selection->setEnabled(arg1);
}

void FrmSetting::on_ckbMetaEnable_stateChanged(int arg1)
{
    ui->fra_meta->setEnabled(arg1);
}

void FrmSetting::on_ckbReadEnable_stateChanged(int arg1)
{
    ui->fra_read_tag_data->setEnabled(arg1);
    ui->ckbMetaTagData->setChecked(arg1);
}

void FrmSetting::on_ckbWriteEnable_stateChanged(int arg1)
{
    ui->fra_embd_cmd_write->setEnabled(arg1);
}

void FrmSetting::on_ckbLockEnable_stateChanged(int arg1)
{
    ui->fra_embd_cmd_lock->setEnabled(arg1);
}

void FrmSetting::on_ckbLockUserMem_stateChanged(int arg1)
{
    ui->cbbLockUserMem->setEnabled(arg1);
}

void FrmSetting::on_ckbLockTIDMem_stateChanged(int arg1)
{
    ui->cbbLockTIDMem->setEnabled(arg1);
}

void FrmSetting::on_ckbLockEPCMem_stateChanged(int arg1)
{
    ui->cbbLockEPCMem->setEnabled(arg1);
}

void FrmSetting::on_ckbLockAccessPwd_stateChanged(int arg1)
{
    ui->cbbLockAccessPwd->setEnabled(arg1);
}

void FrmSetting::on_ckbLockKillPwd_stateChanged(int arg1)
{
    ui->cbbLockKillPwd->setEnabled(arg1);
}

void FrmSetting::on_ckbMetaTagData_stateChanged(int arg1)
{
    ui->ckbReadEnable->setChecked(arg1);
}
